
export class Node {
    id: string;
    text: string;
    desc: string;
    children: Node[] = [];
    parent: Node;
    clickable: boolean;
    indexInParent: number;
    className: string;
    visibleToUser: boolean;
    constructor(private node: UiObject) {
        this.className = node?.className()
        this.id = node?.id()
        this.text = node?.text()
        this.desc = node?.desc();
        this.clickable = node?.clickable()
        this.indexInParent = this.node?.indexInParent()
        this.visibleToUser = !!this.node?.visibleToUser()
    }
    visit(visitor: Visitor, ctx: Context) {
        return visitor.visitNode(this, ctx)
    }
    click() {
        if (this.clickable) return this.node?.click()
        throw new Error(`该Node不可点击`)
    }
    clickOrRect() {
        if (this.clickable) return this.node?.click()
        const bounds = this.node.bounds()
        return click(bounds.centerX(), bounds.centerY())
    }
    clickOrParent(maxDeep: number = 3) {
        if (this.clickable) return this.node?.click()
        if (maxDeep === 0) return false;
        if (this.parent) return this.parent.clickOrParent(maxDeep - 1)
    }
    toJson() {
        return {
            id: this.id,
            text: this.text,
            children: this.children.map(c => c.toJson()),
            clickable: this.clickable
        }
    }
    indexInChildren(node: Node) {
        return this.children.findIndex(it => it === node)
    }
    prev(len: number = 1) {
        return this.parent.children[this.indexInParent - len]
    }
    next(len: number = 1) {
        return this.parent.children[this.indexInParent + len]
    }
    spipeUp() {
        // 导入AutoJS依赖
        const height = device.height;
        const width = device.width;
        // 模拟上划操作
        swipe(width / 2, height * 4 / 5, width / 2, height / 10, 300);
    }
}

export interface Visitor {
    visitNode(node: Node, ctx: Context): any;
}

export class Context {
    private cache: Map<string, any> = new Map()
    set(key: string, val: object) {
        const data = this.get(key) || {}
        this.cache.set(key, { ...data, ...val })
    }
    get(key: string) {
        return this.cache.get(key)
    }
}